//
//  JYTHttpClient.m
//  JYT_IOS
//
//  Created by nxa-tankeke on 16/11/15.
//  Copyright © 2016年 com.yuan. All rights reserved.
//

#import "JYTHttpClient.h"
#import "JYTUserManager.h"

@implementation JYTHttpClient

+ (JYTHttpClient *)sharedInstance {
    
    static dispatch_once_t singleOneToken;
    
    static JYTHttpClient* client;
    
    dispatch_once( &singleOneToken, ^{
        
        client = [[JYTHttpClient alloc] init];
    });
    
    [[JYTUserManager shared] setUrlToHttpClient:client];
    
    return client;
}

- (instancetype)init
{
    self = [super init];
    
    if (self) {
        self.urlType = userCenterUrl;
        //设置 基本地址
        self.baseUrl = @"http://183.62.167.18:9090/service/app/";
        self.cityUrl = @"http://183.62.167.18:9090/service/app/";
        self.zoneUrl = @"http://183.62.167.18:9090/service/app/";

    }
    
    return self;
}

//post 请求
- (void)post:(NSString *)path withParam:(NSDictionary *)param
{
    NSString *curl = [self getUrl];
    
    NSString *url = [NSString stringWithFormat:@"%@%@", curl, path];
    
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
    
    //序列化请求 必须添加此行
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    [manager.requestSerializer setValue:@"application/json;" forHTTPHeaderField:@"Accept"];
    [manager.requestSerializer setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    
    //设置超时
    [manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
    manager.requestSerializer.timeoutInterval = 10.f;
    [manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
    
    
    //序列化请求响应 必须添加此行 直接转化为json
    manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingMutableContainers];
    
    //序列化请求响应 必须添加此行 默认为data
    //    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    
    NSDictionary *params = [self mergeDic:param];
    
    if (!params) {
        [self performFailedCallback:nil withError:nil];
    }
    
//    [manager POST:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
//        
//    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        [self performSuccessfulCallback:task withData:responseObject];
//        
//    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        [self performFailedCallback:task withError:error];
//    }];
    
//    [manager POST:url parameters:params success:^(NSURLSessionDataTask *task, id responseObject) {
//        
//         [self performSuccessfulCallback:task withData:responseObject];
//    } failure:^(NSURLSessionDataTask *task, NSError *error) {
//        
//        [self performFailedCallback:task withError:error];
//    }];
    
    [manager POST:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [self performSuccessfulCallback:task withData:responseObject];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self performFailedCallback:task withError:error];
    }];
}

- (NSString *)getUrl
{
    NSString *url = nil;
    
    UrlType urlType = self.urlType;
    
    switch (urlType) {
        case userCenterUrl:
            
            url = self.baseUrl;
            break;
            
        case userCityUrl:
            
            url = self.cityUrl;
            break;
            
        case userZoneUrl:
            
            url = self.zoneUrl;
            break;
            
        default:
            url = self.baseUrl;
            break;
    }
    
    return url;
}


- (NSMutableDictionary *)mergeDic:(NSDictionary *)dic
{
    
    if (!dic) {
        return nil;
    }
    
    NSMutableDictionary *mdic =[NSMutableDictionary dictionary];
    //
    NSMutableDictionary *entityDic =[NSMutableDictionary dictionary];
    
    NSMutableDictionary *transferDataDic = [NSMutableDictionary dictionaryWithDictionary:dic];
    
    NSString *CommandCode = dic[@"CommandCode"];
    if (!CommandCode) {
        return nil;
    }
    [mdic setObject:CommandCode forKey:@"CommandCode"];
    
    [transferDataDic removeObjectForKey:@"CommandCode"];
    //移除CommandCode 后剩下的是 TransferDataDic
    [transferDataDic setObject:@"S" forKey:@"RoleType"];
    [transferDataDic setObject:@"Android" forKey:@"PlatformType"];
    
    
    NSString *transfer = [self converseToJson:transferDataDic];
    
    if (!transfer) {
        return nil;
    }
    
    [mdic setObject:transfer forKey:@"TransferData"];
    
    [mdic setObject:@"1478831976709" forKey:@"Marker"];
    
    [entityDic setObject:mdic forKey:@"entity"];
    
    NSString *requestStr = [self converseToJson:entityDic];
    
    MyLog(@"\n\nrequest text:\n%@\n\n", requestStr);
    
    return entityDic;
}


- (NSString *) converseToJson:(id) param
{
    NSError *error = nil;
    NSString *jsonString = nil;
    
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:param options:10 error:&error];
    
    if ([jsonData length] > 0 && error == nil){
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    
    else if ([jsonData length] == 0 && error == nil){
        NSLog(@"No data was returned after serialization.");
    }
    
    else if (error != nil){
        NSLog(@"An error happened = %@", error);
        @throw error;
    }
    
    return jsonString;
}


- (void) performFailedCallback:(NSURLSessionDataTask *)task withError:(NSError *)error
{
    if (!error) {
        self.errorCallbackHandler(nil, nil);
        return;
    }
    NSURLResponse *response = task.response;
    NSURLRequest *currentRequest = task.currentRequest;
    
    NSLog(@"\n\ncurrentRequest url:\n%@\n\n", currentRequest.description);
    
    NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];
    NSLog(@"\n\nresponse code: %ld(0:成功   1:失败)\n\n",(long)responseCode);
    
    NSLog(@"Httperror:%@%ld\n", error.localizedDescription,(long)error.code);
    
    dispatch_async(dispatch_get_main_queue(), ^{
        self.errorCallbackHandler(nil, nil);
    });
}



- (void) performSuccessfulCallback:(NSURLSessionDataTask *)task withData:(id)data
{
    NSURLResponse *response = task.response;
    
    NSURLRequest *currentRequest = task.currentRequest;
    NSLog(@"\n\ncurrentRequest url:\n%@\n\n", currentRequest.URL);
    
    NSInteger responseCode = [(NSHTTPURLResponse *)response statusCode];
    NSLog(@"\n\nresponse code: %ld (200:成功   其他:失败)\n\n",(long)responseCode);
    
    
    if (responseCode == 200) {
        
        NSString *responseString = nil;
        NSDictionary* respDic = nil;
        
        if ([data isKindOfClass:[NSDictionary class]]) {
            responseString = [self converseToJson:data];
            respDic = (NSDictionary *)data;
        } else if ([data isKindOfClass:[NSData class]]) {
            
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
            responseString = [self converseToJson:dict];
            
            respDic = dict;
        } else {
            responseString = @"[{无数据}]";
        }
        
        MyLog(@"\n\nresponse text:\n%@\n\n",responseString);
        
        if (![data isKindOfClass:[NSDictionary class]] || !data) {
            dispatch_async(dispatch_get_main_queue(), ^{
                self.errorCallbackHandler(@"9999", @"服务器内容错误");
            });
        }
        
        if (respDic != nil) {
            
            __block NSString *status = respDic[@"ErrorCode"];
            
            __block NSString *msg = respDic[@"ErrorInfo"];
            
            __block NSNumber * pageCount = respDic[@"PageCount"];
            
            __block NSString *ExecuteResult = respDic[@"ExecuteResult"];
            //
            __block id data = nil;
            
            __block id resultInfo = respDic[@"ResultInfo"];
            
            __block id rdata = [NSMutableDictionary dictionary];
            
            if ([resultInfo isKindOfClass:[NSString class]]) {
                
                data = [self dictionaryWithJsonString:resultInfo];
                
            } else {
                
                data = resultInfo;
            }
            
            if (pageCount) {
                [rdata setObject:pageCount forKey:@"PageCount"];
            }
            
            if (data) {
                [rdata setObject:data forKey:@"data"];
            }
            if (ExecuteResult) {
                [rdata setObject:ExecuteResult forKey:@"ExecuteResult"];
            }
            
            dispatch_async(dispatch_get_main_queue(), ^{

                if ([@"0" isEqualToString:status]) {
                    if (data == nil) {
                        self.finishCallbackHandler(nil, status, msg);
                    } else {
                        self.finishCallbackHandler(rdata, status, msg);
                    }
                } else {
                    self.errorCallbackHandler(status, msg);
                }
            });
        } else {
            dispatch_async(dispatch_get_main_queue(), ^{
                self.errorCallbackHandler(@"9999", @"服务器内容错误");
            });
        }
    } else {
        dispatch_async(dispatch_get_main_queue(), ^{
            self.errorCallbackHandler(@"9999", @"服务器内容错误");
        });
    }
}


- (id)dictionaryWithJsonString:(NSString *)jsonString
{
    if (jsonString == nil) {
        
        return jsonString;
        
    }
    
    NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    
    NSError *err;
    
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err];
    
    if(err) {
        
        NSLog(@"\n不是json字符串直接返回该字符串\njson解析失败：\n%@\n",err);
        
        return jsonString;
    }
    
    return dic;
    
}


- (void)currentNetworkStatusWithHandler:(void(^)(NSString *status, BOOL success))handler
{
    //1.创建网络监测者
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    
    /*枚举里面四个状态  分别对应 未知 无网络 数据 WiFi
     typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
     AFNetworkReachabilityStatusUnknown          = -1,      未知
     AFNetworkReachabilityStatusNotReachable     = 0,       无网络
     AFNetworkReachabilityStatusReachableViaWWAN = 1,       蜂窝数据网络
     AFNetworkReachabilityStatusReachableViaWiFi = 2,       WiFi
     };
     */
    
    __block NSString *statusStr = @"";
    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        //这里是监测到网络改变的block  可以写成switch方便
        //在里面可以随便写事件
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
            { NSLog(@"未知网络状态");
                statusStr = @"未知网络状态";
                handler(statusStr, YES);
            }
                break;
            case AFNetworkReachabilityStatusNotReachable:
            {
                NSLog(@"无网络");
                statusStr = @"无网络";
                handler(statusStr, NO);
                
                
            }
                break;
                
            case AFNetworkReachabilityStatusReachableViaWWAN:
            {
                NSLog(@"蜂窝数据网");
                statusStr = @"蜂窝数据网";
                handler(statusStr, YES);
                
            }
                break;
                
            case AFNetworkReachabilityStatusReachableViaWiFi:
            {
                NSLog(@"WiFi网络");
                statusStr = @"WiFi网络";
                handler(statusStr, YES);
                
            }
                
                break;
                
            default:
                handler(statusStr, NO);
                
                break;
        }
        
    }] ;
    
}


-(NSString *) md5_base64:(NSString *)str
{
    if (str == nil) {
        return nil;
    }
    
    const char *cStr = [str UTF8String];
    
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    
    CC_MD5( cStr, (unsigned int)strlen(cStr), digest );
    
    NSData * base64 = [[NSData alloc]initWithBytes:digest length:CC_MD5_DIGEST_LENGTH];
    
    base64 = [GTMBase64 encodeData:base64];
    
    NSString * output = [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding];
    
    return output;
}

@end
